package cn.xo68.ide.plugin.common.component;

import cn.xo68.core.common.Charsets;
import cn.xo68.core.util.JsonUtil;
import cn.xo68.ide.plugin.common.PluginConstants;
import cn.xo68.ide.plugin.common.PluginPathUtils;
import cn.xo68.ide.plugin.common.git.CloneRepositoryRun;
import cn.xo68.ide.plugin.common.git.GitClient;
import cn.xo68.ide.plugin.common.git.GitRun;
import cn.xo68.ide.plugin.common.git.PullRun;
import cn.xo68.ide.plugin.common.jobs.GitJob;
import cn.xo68.ide.plugin.common.log.ToolSuiteLogAppenderOnProject;
import cn.xo68.ide.plugin.common.service.Settings;
import cn.xo68.ide.plugin.common.template.TemplateConfig;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.ProjectManagerListener;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.util.messages.MessageBusConnection;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.PropertyConfigurator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;

/**
 * 组件启动处理理
 * @author wuxie
 * @date  2018-10-26
 */
public class StarupApplicationComponent implements ApplicationComponent, Disposable {
    private static final Logger logger = LoggerFactory.getLogger(StarupApplicationComponent.class);

    public static StarupApplicationComponent getInstance(){
        return ApplicationManager.getApplication().getComponent(StarupApplicationComponent.class);
    }

    public static String LOG_FORMAT="%-d{HH:mm:ss} [%p] %c -  %m%n";

    /**
     * idea程序目录
     */
    //public static String IDEA_PATH="idea.root.path";

    private final List<Project> projects;

    /**
     * 最后操作的项目
     */
    private Project lastOperateProject= null;

    public StarupApplicationComponent() {
        this.projects = new LinkedList<>();
    }


    @Override
    public void initComponent() {
        MessageBusConnection busConnection = ApplicationManager.getApplication().getMessageBus().connect(this);
        busConnection.subscribe(ProjectManager.TOPIC, new ProjectListener());

        String homePath = VfsUtil.getUserHomeDir().getCanonicalPath();
        //PathManager.getHomePath();
        Properties props = System.getProperties();

        PluginPathUtils.setDataPath(homePath+ File.separator + PluginPathUtils.IDE_PLUGIN_DATA_FOLDER);
        final String dataPath=PluginPathUtils.getDataPath();
        if(notExistsAndCreateFail(dataPath)){
            return;
        }

        final String logPath=PluginPathUtils.getLogPath();
        PluginPathUtils.setLogPath(logPath);
        if(notExistsAndCreateFail(logPath)){
            return;
        }

        final String storePath=PluginPathUtils.getStorePath();
        PluginPathUtils.setStorePath(storePath);
        if(notExistsAndCreateFail(storePath)){
            return;
        }

        // 配置日志
        PropertyConfigurator.configure(this.getClass().getClassLoader().getResource("/log4j.properties"));

        //追加日志输出到自定义控制吧
        ToolSuiteLogAppenderOnProject toolSuiteLogAppenderOnProject=new ToolSuiteLogAppenderOnProject(new PatternLayout(LOG_FORMAT));
        // toolSuiteLogAppender=new ToolSuiteLogAppender(new PatternLayout(LOG_FORMAT));
        org.apache.log4j.Logger.getRootLogger().addAppender(toolSuiteLogAppenderOnProject);
        //org.apache.log4j.Logger.getRootLogger()


        //ApplicationManager.getApplication().assertIsDispatchThread();



        //logger.info("projects: {}",this.projects);

//        new Thread(()->{
//            int waitCount=0;
//            int maxWaitCount=100;
//            while (projects.size() < 1 && waitCount < maxWaitCount){
//                try {
//                    Thread.sleep(200);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                    logger.error("加载异常", e);
//                }
//                waitCount++;
//            }
//            if(projects.size()>0 ){
//                logger.info(">>  starup success");
//                logger.info("projects: {}",this.projects);
//
//                gitPull();
//            } else {
//                logger.warn("日志系统初始化疑似失败");
//            }
//
//        }).start();

        //ApplicationManager.getApplication().getComponent()

    }

    private boolean notExistsAndCreateFail(final String path){
        File tempDir=new File(path);
        if(!tempDir.exists() && !tempDir.mkdirs()){
            ApplicationManager.getApplication().invokeLater(()-> {
                Messages.showMessageDialog("在Intellij idea安装目录下创建插件文件夹["+ path +"]失败，请确保当前用户的写权限！","错误提示", Messages.getErrorIcon());
            });
            return true;
        }
        return false;
    }

    @Override
    public void disposeComponent() {

    }

    void addProject(Project project) {
        this.projects.add(project);
    }

    void removeProject(Project project) {
        this.projects.remove(project);
    }

    public List<Project> getProjects() {
        return projects;
    }

    public Project getProject(){
        if( this.projects!=null && this.projects.size()>0){
            return this.projects.get(0);
        }
        return null;
    }

    public Project getLastOperateProject() {
        if(lastOperateProject==null){
            return getProject();
        }
        return lastOperateProject;
    }

    public void setLastOperateProject(Project lastOperateProject) {
        this.lastOperateProject = lastOperateProject;
    }

    public GitClient getGitClient(){
        File localDir=new File(PluginPathUtils.getStorePath());
        String remotePaht= Settings.getInstance().getGitSetting().getGitRepository();
        //"https://gitee.com/nnsword/wts-data.git";
        GitClient gitClient=new GitClient(localDir,remotePaht);
        return  gitClient;
    }

    public void gitPull(){
        Settings settings=Settings.getInstance();
        GitClient gitClient=getGitClient();
        try {
            gitClient.init();

            List<GitRun> gitRuns=new ArrayList<>();
            if(gitClient.localRepositoryExist()) {
                gitRuns.add(new PullRun(null,settings.getGitSetting().getUserName(), settings.getGitSetting().getPassword()));

            }else {
                gitRuns.add(new CloneRepositoryRun());
            }
            GitJob gitJob=new GitJob("初始化数据", gitClient, gitRuns);
            ToolSuiteJobManager toolSuiteJobManager=this.projects.get(0).getComponent(ToolSuiteJobManager.class);
            toolSuiteJobManager.submit(gitJob);
        } catch (IOException e) {
            logger.error("gitclient初始化异常", e);
        }
    }

    public File getTemplateConfigFile() {
        return new File(PluginPathUtils.getTemplatePath(), PluginConstants.CONFIG_TEMPLATE_CONFIG_FILE);
    }

    public Boolean templateConfigExists() {
        return getTemplateConfigFile().exists();
    }

    public TemplateConfig loadTemplateConfig() {
        if(!templateConfigExists()) {
            return null;
        }
        TemplateConfig templateConfig=null;
        try {
            templateConfig = JsonUtil.getInstance().read(getTemplateConfigFile(), Charsets.UTF8, TemplateConfig.class);
        } catch (Exception e) {
            logger.error("加载模板配置信息异常", e);
        }
        return templateConfig;
    }

    @Override
    public void dispose() {
        Disposer.dispose(this);
    }

    private class ProjectListener implements ProjectManagerListener {

        @Override public void projectOpened(Project project) {
            addProject(project);
        }

        @Override public void projectClosed(Project project) {
            //nothing to do
        }

        @Override public void projectClosing(Project project) {
            removeProject(project);
        }
    }
}
